<?php


namespace app\admin\controller;
use app\admin\model\{Prize as PrizeModel,PrizeCode};    // 抽奖模型
use think\facade\Db;
use think\App;
use think\cache\driver\Redis;
use app\common\BaseController;

// 奖品管理
class Prize extends BaseController
{



    /**
     * 奖品列表
     * date 2021/3/29 16:40
     */
    public function prize_list() {
            $page  = (int)request()->param('page', 1);
            $limit  = (int)request()->param('limit', 10);
            $search = request()->param();
            $wheres = [];
            if(isset($search['name']) && $search['name'] !=''){
                $wheres[] = ['name','like',"%{$search['name']}%"];
            }
            $query  = PrizeModel::where($wheres);
            $total  = $query->count();
            $data   = $query->page($page, $limit)->order('sort desc')->select();
            $redis = redis_instance();
            $type_map = [1=>'实物', 2=>'虚拟卡券', 3=>'其他卡券', 4=>'谢谢参与'];
            foreach ($data as $key => $item) {
                  // 奖品类型
                  $item['type_text'] = $type_map[$item['type']];
                     // 奖品redis库存
                  $item['redis_stock'] = $redis->lLen("{$this->redis_key}:PrizeStock:{$item['id']}");
                    // 中奖次数
                $item['win_times_text'] = $item['win_times'] == 1 ? '只中1次' : '不限次数';
                  // 奖品总库存
                  $item['stock_text'] = $item['stock'] > 0 ? $item['stock'] : '不限';
                   // 虚拟卡券库存为0代表没有导入券码，而不是不限
                if($item['type'] == 2) $item['stock_text'] = $item['stock'];
                  // 每日库存
                  $item['day_stock_text'] = $item['day_stock'] > 0 ? $item['day_stock'] : '不限';
                  // 今日发放数
                  $item['today_send_num'] = Db::name('prize_log')->where(['prize_id'=>$item['id'], 'log_date'=>date('Y-m-d')])->count();
                  // 累计发放数
                  $item['send_num'] = Db::name('prize_log')->where('prize_id', $item['id'])->count();

                  //概率
                  $item['ratio_text'] =  $item['status'] == 1 ? round(100 * ($item['ratio'] / Db::name('prize')->where('status',1)->sum('ratio')),2) .'%' : 0;
            }
            return $this->success('', [
                'start' => $page,
                'limit' => $limit,
                'data'  => $data,
                'total' => $total,
            ]);
    }

    /**
     * 添加奖品
     * date 2021/3/23 10:35
     */
    public function create() {
        $data = request()->post();
        
        try {
            $this->validate($data, [
                'name' => 'require',
            ], [
               'name.require'      => '名称必须',
            ]);
        } catch (\Exception $e) {
            json_response(0,$e->getError());
        }
            $res = PrizeModel::create($data);
            // redis队列存入
            if(!empty($data['stock'])) {
                $redis = redis_instance();
                $redis->multi(\Redis::PIPELINE);
                for($i=1; $i<=$data['stock']; $i++) {
                    $redis->lPush("{$this->redis_key}:PrizeStock:{$res->id}", 1);
                }
                $redis->exec();
            }
            if($data['type'] == 2) {
                $data['stock'] = $data['day_stock'] = $data['ratio'] = 0;
                $data['win_times'] = 1;
            }
            $res ? json_response(1, '添加成功') : json_response(0, '添加失败');
    }

    /**
     * 编辑奖品
     * date 2021/3/23 11:21
     */
    public function edit() {
        $data = request()->post();
        try {
            $this->validate($data, [
                'id' => 'require',
                'name' => 'require',
            ], [
                'id.require'      => 'id必须',
               'name.require'      => '名称必须',
            ]);
        } catch (\Exception $e) {
            json_response(0,$e->getError());
        }
          // 奖品类型/库存不可编辑
          unset($data['type'], $data['stock']);
        $res = PrizeModel::update($data);
        $res ? json_response(1, '编辑成功') : json_response(0, '编辑失败');
    }

    /**
     * 删除奖品
     * date 2021/3/23 11:22
     */
    public function delete() {
        $prize_id = param_check('ids');
        $res = PrizeModel::where('id', $prize_id)->delete();
        if($res) {
            // 同步删除redis库存
            $redis = redis_instance();
            $redis->del("{$this->redis_key}:PrizeStock:{$prize_id}");

            // 删除虚拟卡券券码
//            db('prize_code')->where('prize_id', $prize_id)->delete();

            json_response(1, '删除成功');
        }else {
            json_response(0, '删除失败');
        }
    }

    /**
     * 添加库存
     * date 2021/4/11 17:36
     */
    public function add_stock() {
        $id = param_check('id');
        $stock = param_check('stock');
            // 虚拟卡券或者不限数量奖品不可以添加库存
            $prize_info = PrizeModel::where('id', $id)->find();
            if($prize_info['type'] != 2 && $prize_info['stock'] > 0) {
                // 修改数据库
                $res = PrizeModel::where('id', $id)->update([
                    'stock'         => [$stock > 0 ? 'INC' : 'DEC', $stock],
                    'update_time'   => time()
                ]);
                // 存入redis
                if($res) {
                    $redis = redis_instance();
                    $redis->multi(\Redis::PIPELINE);
                    if($stock > 0){
                        for($i=1; $i<=$stock; $i++) {
                            $redis->lPush("{$this->redis_key}:PrizeStock:{$id}", 1);
                        }
                    }else{
                        for($i=1; $i<=abs($stock); $i++) {
                            $redis->rPop("{$this->redis_key}:PrizeStock:{$id}");
                        }
                    }
                    $redis->exec();
                    json_response(1, '操作库存成功');
                }else {
                    json_response(0, '添加库存失败');
                }
            }else {
                json_response(0, '非法操作');
            }
        
    
    }

    /**
     * 奖品上架下架
     * date 2021/4/2 10:58
     */
    public function prize_switch() {
        $id      = param_check('id');
        $checked = param_check('checked', 0);
        $res = PrizeModel::where('id', $id)->update([
            'status'        => $checked ? 1 : 0,
            'update_time'   => time()
        ]);
        $res ? json_response(1, '修改成功') : json_response(0, '修改失败');
    }

        /**
     * 详情
     * @param int $id
     * @return \think\response\Json
     * @author Sam
     * @date 2022-04-26
     */
    public function detail(int $id): \think\response\Json
    {
        try {
            $row  = PrizeModel::where('id', $id)->find();
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return $this->error($e->getMessage());
        }

        return $this->success('', $row);
    }

    /**
     * 虚拟卡券列表
     * date 2021/4/2 11:15
     */
    public function prize_code_list() {
            $prize_id = param_check('prize_id');
            $page  = (int)request()->param('page', 0);
            $limit  = (int)request()->param('limit', 10);
            $query  = PrizeCode::where('prize_id',$prize_id);
            $total  = $query->count();
            $data   = $query->page($page, $limit)->order('id desc')->select();
            $prize_name = PrizeModel::where('id', $prize_id)->value('name');
            foreach ($data as $key => $item) {
                $item['prize_name'] = $prize_name;
                $item['status_text'] = $item['status'] == 1 ? '已发出' : '未发出';
                $item['send_time']   = $item['status'] == 1 ? date('Y-m-d H:i:s', $item['send_time']) : '-';
            }
            return $this->success('', [
                'start' => $page,
                'limit' => $limit,
                'data'  => $data,
                'total' => $total
            ]);
    }

    /**
     * 虚拟卡券导入模板下载
     * date 2021/4/2 11:32
     */
    public function prize_code_down_tmp() {
        header('Location: https://pilihuo.oss-cn-hangzhou.aliyuncs.com/resource/csv_template/%E8%99%9A%E6%8B%9F%E5%8D%A1%E5%88%B8%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.csv');
    }

    /**
     * 导入虚拟卡券
     * date 2021/4/4 18:12
     */
    public function prize_code_import() {
        set_time_limit(0);
        $prize_id = param_check('prize_id');
        if(empty($_FILES['file'])) json_response(0, '请选择文件');
        $redis = redis_instance();
        $data = big_csv_to_array($_FILES['file']['tmp_name']);
        $num = 0;
        foreach ($data as $k=> $item) {
            if($k == 0) continue;
            if(!empty($item[0])) {
                $code = trim($item[0]);
                if(PrizeCode::where('code', $code)->find()) {
                    \json_response(0, '第'.($num+1).'行，'.$code.'卡券码已存在');
                    continue;
                }
                $redis->lPush("{$this->redis_key}:PrizeStock:{$prize_id}", $code);
                PrizeCode::create([
                    'prize_id'    => $prize_id,
                    'code'        => $code,
                    'create_time' => time()
                ]);
                $num += 1;
            }
        }
        PrizeModel::where('id', $prize_id)->update([
            'stock'         => ['INC', $num],
            'update_time'   => time()
        ]);
        json_response(1,"成功导入{$num}条数据");
    }


    /**
     * 中奖记录导出
     * @return void
     * @author Sam
     * @date 2022-04-28
     */
    public function prize_log_export(){
        $map = [];
            if(!empty($_REQUEST['prize_id'])) $map[] = ['a.prize_id', '=', $_REQUEST['prize_id']];
            if(isset($_REQUEST['status']) && $_REQUEST['status'] !='') $map[] = ['a.status', '=', $_REQUEST['status']];
            if(!empty($_REQUEST['name'])) $map[] = ['a.name', '=', $_REQUEST['name']];
            if(!empty($_REQUEST['mobile'])) $map[] = ['a.mobile', '=', $_REQUEST['mobile']];
            $title = ['编号', '奖品类型','奖品名称','状态','姓名','电话','收货地址','中奖时间'];
            set_time_limit(0); // 设置超时时间
            $filename = '中奖记录' . date('Ymdhis') . '.csv';
            header("Content-type:application/vnd.ms-csv");
            header('content-disposition:attachment; filename="' . $filename . '"');
            ob_end_flush();
            // ob_implicit_flush(true);
            // 写入导出标题
            echo iconv('utf-8', 'gbk', implode(',', $title)) . PHP_EOL;
            $lastId = 0;
            while (true) {
                $list = Db::name('prize_log')
                ->alias('a')
                ->where($map)
                ->where('a.id','>',$lastId)
                ->leftJoin('prize b', 'a.prize_id=b.id')
                ->leftJoin('user c', 'a.user_id=c.id')
                ->field('a.id, a.status, a.name, a.mobile, a.address, a.log_time, a.prize_type, a.prize_name, a.prize_image, c.nickname, c.avatar')
                ->order('a.id ASC')
                ->select();
                $list =  UserModel::where($wheres)->limit(100)->order('id asc')->where('id','>',$lastId)->select()->toArray();
                if (!empty($list)) {
                    foreach ($list as $user) {
                        $item = []; // 初始化数组
                        // 用户信息
                        $item[] = $user['id']; // id
                        if($user['prize_type'] == 1) $item[] = '实物';
                        if($user['prize_type'] == 2) $item[] = '虚拟卡券';
                        if($user['prize_type'] == 3) $item[] = '其他卡券';
                        if($user['prize_type'] == 4) $item[] ='谢谢参与';
                        $item[]  = $user['prize_name'];
                        if($user['status'] == 1) $item[] = '已领取';
                        if($user['status'] == 0) $item[] = '未领取';
                          $item[] = $user['name'];
                          $item[] = $user['mobile'];
                          $item[] = $user['address'];
                          $item[] = $user['create_time'];
                        // 写入内容
                        echo iconv('utf-8', 'gbk//IGNORE', implode(',', $item)) . PHP_EOL;
                        $lastId = $user['id']; // 最大id
                    }
    
                } else {
                    break;
                }
            }
            exit;  
    }
    /**
     * 中奖记录
     * date 2021/4/4 21:49
     */
    public function prize_log() {
        $page  = (int)request()->param('page', 0);
        $limit  = (int)request()->param('limit', 10);
        $map = [];
        if(!empty($_REQUEST['prize_id'])) $map[] = ['a.prize_id', '=', $_REQUEST['prize_id']];
        if(isset($_REQUEST['status']) && $_REQUEST['status'] !='') $map[] = ['a.status', '=', $_REQUEST['status']];
        if(!empty($_REQUEST['user'])) $map[] = ['a.name|a.mobile', 'like', "%{$_REQUEST['user']}%"];
            $query = Db::name('prize_log')
                ->alias('a')
                ->where($map)
                ->leftJoin('prize b', 'a.prize_id=b.id')
                ->leftJoin('user c', 'a.user_id=c.id')
                ->field('a.id, a.status, a.name, a.mobile, a.address, a.log_time, a.prize_type, a.prize_name, a.prize_image, c.nickname, c.avatar');
            $total  = $query->count();
            $data   = $query->page($page, $limit)->order('a.id desc')->select()->toArray();
            foreach ($data as &$item) {
                if($item['prize_type'] == 1) $item['type_text'] = '实物';
                if($item['prize_type'] == 2) $item['type_text'] = '虚拟卡券';
                if($item['prize_type'] == 3) $item['type_text'] = '其他卡券';
                if($item['prize_type'] == 4) $item['type_text'] = '谢谢参与';
                $item['log_time']   = date('Y-m-d H:i:s', $item['log_time']);
                $item['status_text'] = $item['status'] == 1 ? '已领取' : '未领取';
            }
            $prize = PrizeModel::field('id,name')->select();
            return $this->success('', [
                'start' => $page,
                'limit' => $limit,
                'data'  => $data,
                'total' => $total,
                'prize' => $prize
            ]);
    }
}